//
//  BigDecimal.h
//  BigNum
//
//  Created by Sam Jaffe on 9/18/12.
//  Copyright (c) 2012 Sam Jaffe. All rights reserved.
//

#pragma once

#include "BigNum.h"
#include "BigUInt.h"
#include "BigInt.h"

template <class D>
class Decimal;

class BigDecimal;
class InfDecimal;

template <class D>
class Decimal : public BigInt {
protected:
    D exponent;
    Decimal(const unsigned long long value);
    Decimal();
    Decimal(const BigUInt& copy);
    Decimal(const BigUInt& copy, bool sign);
    Decimal(const BigInt& copy);
    Decimal(const Decimal& copy);
    
public:
    void sum(const Decimal& a, const Decimal& b);
    void diff(const Decimal& a, const Decimal& b);
    void product(const Decimal& a, const Decimal& b);
    void quotient(const Decimal& a, const Decimal& b);
    void modulo(const Decimal& a, const Decimal& b);
    
    void bflip(const Decimal& a);
    void band(const Decimal& a, const Decimal& b);
    void bor(const Decimal& a, const Decimal& b);
    void bxor(const Decimal& a, const Decimal& b);
    void bin(const Decimal& a, const Decimal& b);
    void bout(const Decimal& a, const Decimal& b);
    
    Decimal operator% (const Decimal& b) const = delete;
    
    virtual bool operator== (const Decimal& b) const;
    virtual bool operator!= (const Decimal& b) const;
    virtual bool operator>= (const Decimal& b) const;
    virtual bool operator> (const Decimal& b) const;
    virtual bool operator<= (const Decimal& b) const;
    virtual bool operator< (const Decimal& b) const;
};

class BigDecimal : public Decimal<int> {
public:
    BigDecimal(const unsigned long long value);
    BigDecimal();
    BigDecimal(const BigUInt& copy);
    BigDecimal(const BigUInt& copy, bool sign);
    BigDecimal(const BigInt& copy);
    BigDecimal(const BigDecimal& copy);
    
    operator InfDecimal() const;
};

class InfDecimal : public Decimal<BigUInt> {
    InfDecimal(const unsigned long long value);
    InfDecimal();
    InfDecimal(const BigUInt& copy);
    InfDecimal(const BigUInt& copy, bool sign);
    InfDecimal(const BigInt& copy);
    InfDecimal(const InfDecimal& copy);
};
